import {SimpleModel} from "../../framework/model/SimpleModel.ts";
import {
    CurvePath,
    CylinderGeometry,
    DoubleSide,
    LineCurve3,
    Material,
    Mesh,
    MeshPhongMaterial,
    TubeGeometry,
    Vector3
} from "three";

export class Tube extends SimpleModel {

    private static matRoad: Material = new MeshPhongMaterial({
        color: 0xffff00,
        transparent: true,
        opacity: 0.2,
        side: DoubleSide
    })
    private static matTiny: Material = new MeshPhongMaterial({
        color: 0x00ff66,
        transparent: true,
        opacity: 1.0,
        side: DoubleSide
    })
    static radius: number = 1 / 8
    moveStep: number = 0.1
    cp: CurvePath
    tinyCounts: number
    tinyList: Mesh[]

    updateEnable: boolean = false

    constructor() {
        super("Tube")
        this.updateEnable = true
    }

    init(tinyCounts: number, ...points: Vector3): void {
        this.tinyList = []
        this.tinyCounts = tinyCounts
        this.moveStep = 1.0 / this.tinyCounts
        let cp = new CurvePath()
        for (let i = 0; i < points.length - 1; i++) {
            const lineCurve = new LineCurve3(points[i], points[i + 1])
            console.log(points[i], points[i + 1])
            cp.curves.push(lineCurve)
        }
        this.cp = cp
        this.genRoad()
        this.genTiny()
    }

    genRoad(): void {
        let geo = new TubeGeometry(this.cp, 40, Tube.radius, 25)
        let mesh = new Mesh(geo, Tube.matRoad)
        this.scene.add(mesh)
    }

    genTiny(): void {
        console.log("gen tiny", this.tinyCounts)
        console.log("step", this.moveStep)
        let radius = Tube.radius
        for (let i = 0; i < this.tinyCounts; i++) {
            let geo = new CylinderGeometry(radius, radius, radius * 2.0, 100)
            let tiny = new Mesh(geo, Tube.matTiny)
            tiny.userData.process = i * this.moveStep
            tiny.rotation.x = Math.PI / 2
            this.scene.add(tiny)
            this.tinyList.push(tiny)
        }
    }

    update(delta: number): void {
        super.update(delta)
        if (!this.updateEnable) {
            return
        }
        let move = delta * this.moveStep
        for (let i = 0; i < this.tinyCounts; i++) {
            let tiny = this.tinyList[i]
            tiny.userData.process += move
            if (tiny.userData.process >= 1) {
                tiny.userData.process %= 1
            }
            const position = this.cp.getPointAt(tiny.userData.process)
            const tangent = this.cp.getTangentAt(tiny.userData.process)
            tiny.position.copy(position)
            tiny.quaternion.setFromUnitVectors(new Vector3(0, 1, 0), tangent)
        }
    }
}
